package com.dongdongshop.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.dongdongshop.pojo.TbOrder;
import com.dongdongshop.pojo.TbOrderItem;
import com.dongdongshop.service.TbOrderItemService;
import com.dongdongshop.service.TbOrderService;
import com.dongdongshop.vo.TbOrderAndTbOrderItemVO;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;

@RocketMQTransactionListener(txProducerGroup = "tx-group")
public class MQConsumerTransactionListener implements RocketMQLocalTransactionListener {
    @Autowired
    private RedisTemplate redisTemplate;
    @Reference
    private TbOrderService tbOrderService;
    @Reference
    private TbOrderItemService tbOrderItemService;

    /**
     * 1、MQ服务，成功接到事物消息后，执行本方法；
     * 2、处理本地事物，并将本地事物处理结果返回给MQ服务
     *
     * @return COMMIT, ROLLBACK, UNKNOWN;
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        //将本地事物执行状态return到MQ服务，并且保存到redis备份（网络延迟，MQ服务产生回调的时候 可以从redis中获取）
        try {
            //业务处理
            System.out.println(new String((byte[]) message.getPayload()));

            TbOrderAndTbOrderItemVO vo = (TbOrderAndTbOrderItemVO) o;
            TbOrder tbOrder = vo.getTbOrder();
            TbOrderItem tbOrderItem = vo.getTbOrderItem();
            tbOrderService.update(tbOrder); //更新数据库
            tbOrderItemService.update(tbOrderItem);//更新数据库


            //int i = 9 / 0;
        } catch (Exception e) {
            //处理异常返回ROLLBACK
            redisTemplate.opsForValue().set(message.getHeaders().get("TRANSACTION_ID"), "2");
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        //处理成功返回COMMIT
        redisTemplate.opsForValue().set(message.getHeaders().get("TRANSACTION_ID"), "1");
        return RocketMQLocalTransactionState.COMMIT;
    }


    /**
     * MQ服务 由于网络等原因 未收到 本地事物处理结果，回查本地事物处理结果
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        //通过事务id获取 redis中 对应的本地事务执行状态
        String status = (String) redisTemplate.opsForValue().
                get(message.getHeaders().get("TRANSACTION_ID").toString());
        if ("1".equals(status)) {
            return RocketMQLocalTransactionState.COMMIT;
        } else if ("2".equals(status)) {
            //继续处理，或者直接回滚
            return RocketMQLocalTransactionState.ROLLBACK;
        } else {
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}